#pragma once

// vector.h 
// 04/15/2011: created

#include <vector>
#include <armadillo>
#include <limits>
#include <assert.h>

#define POSITIVE_INFINITY (std::numeric_limits<double>::infinity())
#define NEGATIVE_INFINITY (-std::numeric_limits<double>::infinity())

class vec : public arma::vec
{
  typedef arma::vec   __Base;
public:
  vec(int n = 1) : __Base(n) {}
  template <typename T1, typename eop_type> vec(const arma::eOp<T1,eop_type>& v) : __Base(v) {}
  template <typename T1, typename T2, typename eglue_type> vec(const arma::eGlue<T1,T2,eglue_type>& v) : __Base(v) {}

  double cross(const vec& v) {
    assert(this->n_elem >= 2 && v.n_elem >= 2);
    return this->at(0) * v[1] - this->at(1) * v[0];
  }
};

class dataset_type
{
protected:
  const std::vector<vec>& m_set;
  std::vector<int> m_idx;
public:
  dataset_type(const std::vector<vec>& set,int) :  // add a int here to prevent automatic type conversion
    m_set(set), m_idx(n_total())
  {
    for (int i = 0; i < n_total(); i++) m_idx[i] = i;
  }
  dataset_type(const dataset_type& dataset, const std::vector<int>& idx) :
    m_set(dataset.m_set), m_idx(idx)
  {
  }

  int n_total() const { return m_set.size(); }
  int size() const { return m_idx.size(); }
  const vec& operator[](int i) const { return m_set[m_idx[i]]; }
  //vec& operator[](int i) { return m_set[i]; }
};
